#include "actor.h"
#include "action.h"

actor::actor(): faction( FAC_NEUTRAL ),
                busy( false ),
                curaction( NULL )
{
    type = MOB_ACTOR;
}
actor::~actor(){
    if( curaction ) delete curaction;
}

unsigned char actor::getFaction(){
    return faction;
}

bool actor::move(direc_t direction, unsigned int distance){

    int xoff = 0;
    int yoff = 0;
    float rdist = 0;

    if( direction == DIR_UP ){
        yoff = distance;
        rdist = 1.74*distance;
    }else if( direction == DIR_DOWN ){
        yoff = -distance;
        rdist = 1.74*distance;
    }else if( direction == DIR_U_LEFT ){
        xoff = -distance;
        rdist = 1.32*distance;
        if( coordinates.X_coord % 2 ){
            yoff = distance / 2;
        }else{
            if( distance % 2 ){
                yoff = distance / 2 + 1;
            }else{
                yoff = distance / 2;
            }
        }
    }else if( direction == DIR_D_LEFT ){
        xoff = -distance;
        rdist = 1.32*distance;
        if( coordinates.X_coord % 2 ){
            if( distance % 2 ){
                yoff = -(distance / 2 + 1);
            }else{
                yoff = -(distance / 2);
            }
        }else{
            yoff = -(distance/2);
        }
    }else if( direction == DIR_U_RIGHT ){
        xoff = distance;
        rdist = 1.32*distance;
        if( coordinates.X_coord % 2 ){
            yoff = distance / 2;
        }else{
            if( distance % 2 ){
                yoff = distance / 2 + 1;
            }else{
                yoff = distance / 2;
            }
        }
    }else if( direction == DIR_D_RIGHT ){
        xoff = distance;
        rdist = 1.32*distance;
        if( coordinates.X_coord % 2 ){
            if( distance % 2 ){
                yoff = -(distance / 2 + 1);
            }else{
                yoff = -(distance / 2);
            }
        }else{
            yoff = -(distance/2);
        }
    }

    coord_t crd = coordinates;
    crd.X_coord += xoff;
    crd.Y_coord += yoff;

    if( !parentMap->isCellWalkable(crd) ) return false;

    cell_t* cell = parentMap->getCell( crd.X_coord, crd.Y_coord );
    setStatus( CELL_OCCUPIED, cell, true );
    setStatus( CELL_OCCUPIED, parentMap->getCell(coordinates.X_coord,coordinates.Y_coord), false );

    if( curaction ) delete curaction;
    curaction = new action_move(this,crd,rdist,10000);

    coordinates = crd;

    return true;

}

bool actor::isBusy(){
    return busy;
}
action* actor::getCurAction(){
    return curaction;
}
void actor::endAction(){
    delete curaction;
    curaction = NULL;
}

void actor::exec_AI(){
    if( !curaction ){
        curaction = new action_idle(this);
        curaction->setDuration(2000);
    }
}

f_coord_t actor::getFCoord(){
    f_coord_t coord = mapObject::getFCoord();
    if( curaction ){
        if( curaction->getType() == AC_TY_MOVE ){
            f_coord_t origcoord;
            float progress = curaction->getProgress();
            origcoord.X_coord = ((action_move*)curaction)->getOrig().X_coord;
            origcoord.Y_coord = getGridY(((action_move*)curaction)->getOrig().Y_coord,((action_move*)curaction)->getOrig().X_coord);
            coord.X_coord = progress * coord.X_coord + (1-progress) * origcoord.X_coord;
            coord.Y_coord = progress * coord.Y_coord + (1-progress) * origcoord.Y_coord;
        }
    }
    return coord;
}
